package com.zycfc.zsf.boot.job;

import com.dangdang.ddframe.job.reg.zookeeper.*;
import org.springframework.core.env.*;
import com.zycfc.zsf.boot.core.common.*;
import com.dangdang.ddframe.job.api.*;
import com.dangdang.ddframe.job.api.simple.*;
import com.dangdang.ddframe.job.config.simple.*;
import com.dangdang.ddframe.job.config.dataflow.*;
import com.zycfc.zsf.boot.job.api.*;
import com.dangdang.ddframe.job.config.script.*;
import com.dangdang.ddframe.job.config.*;
import com.dangdang.ddframe.job.lite.config.*;
import org.springframework.beans.*;
import com.zycfc.zsf.boot.util.text.*;
import org.springframework.scheduling.support.*;
import com.zycfc.zsf.boot.job.enums.*;
import org.springframework.util.*;
import com.dangdang.ddframe.job.executor.handler.*;
import com.dangdang.ddframe.job.event.rdb.*;
import com.dangdang.ddframe.job.lite.api.listener.*;
import com.zycfc.zsf.boot.job.core.*;
import com.dangdang.ddframe.job.reg.base.*;
import com.dangdang.ddframe.job.event.*;
import com.zycfc.zsf.boot.job.common.*;
import java.util.*;
import org.slf4j.*;

public class ZsfJobBeanProcessor
{
    private static final Logger log;
    private ZookeeperRegistryCenter zookeeperRegistryCenter;
    private String namespace;
    private Environment env;
    public static final String CHAIN_BRANCH_CRON = "0 0 0 ? * 6L 2085-2086";
    
    public ZsfJobBeanProcessor(final String namespace, final ZookeeperRegistryCenter zookeeperRegistryCenter, final Environment env) {
        this.zookeeperRegistryCenter = zookeeperRegistryCenter;
        this.namespace = namespace;
        this.env = env;
    }
    
    public void init() {
        final String[] beanDefinitionNames;
        final String[] beans = beanDefinitionNames = SpringContextHelper.getApplicationContext().getBeanDefinitionNames();
        for (final String beanName : beanDefinitionNames) {
            try {
                final Object bean = SpringContextHelper.getBean(beanName);
                this.initializationBean(bean, beanName);
            }
            catch (Exception e) {
                ZsfJobBeanProcessor.log.error("ZsfJob: \u52a0\u8f7d\u4f5c\u4e1a\u5f02\u5e38, jobName: {}", (Object)beanName, (Object)e);
            }
        }
    }
    
    public Object initializationBean(final Object bean, final String beanName) throws BeansException {
        if (bean instanceof ElasticJob) {
            if (!(bean instanceof ZsfJobConfig)) {
                throw new IllegalArgumentException("\u5b9e\u73b0 com.dangdang.ddframe.job.api.ElasticJob\u63a5\u53e3\u7684\u7c7b\u5fc5\u987b\u4e5f\u8981\u5b9e\u73b0" + ZsfJobConfig.class.getName());
            }
            ZsfJobBeanProcessor.log.info("ZsfJob: \u5f00\u59cb\u52a0\u8f7d\u4f5c\u4e1a[{}]", (Object)beanName);
            final ZsfJobConfig elasticJobConfig = (ZsfJobConfig)bean;
            ZsfJobProperties jobProperties = elasticJobConfig.jobProperties();
            if (null == jobProperties) {
                final ZsfJob elasticjob = bean.getClass().getAnnotation(ZsfJob.class);
                if (elasticjob == null) {
                    throw new IllegalArgumentException("\u7f3a\u5931@Elasticjob\u914d\u7f6e" + ZsfJobConfig.class.getName());
                }
                jobProperties = new ZsfJobProperties(elasticjob);
            }
            this.checkIdempotent(jobProperties);
            JobInfPool.putBeans(jobProperties.getJobName(), beanName);
            final JobCoreConfiguration jobCoreConfiguration = this.createJobCoreConfiguration(elasticJobConfig, jobProperties);
            JobTypeConfiguration jobTypeConfiguration;
            if (bean instanceof SimpleJob) {
                jobTypeConfiguration = (JobTypeConfiguration)new SimpleJobConfiguration(jobCoreConfiguration, bean.getClass().getCanonicalName());
            }
            else if (bean instanceof BaseDataflowJob) {
                final boolean streamingProcess = ((BaseDataflowJob)bean).streamingProcess();
                jobTypeConfiguration = (JobTypeConfiguration)new DataflowJobConfiguration(jobCoreConfiguration, bean.getClass().getCanonicalName(), streamingProcess);
            }
            else {
                if (!(bean instanceof BaseScriptJob)) {
                    throw new IllegalArgumentException("ElasticJob must implement BaseSimpleJob or BaseDataflowJob or BaseScriptJob.");
                }
                final String scriptCommandLine = ((BaseScriptJob)bean).scriptCommandLine();
                jobTypeConfiguration = (JobTypeConfiguration)new ScriptJobConfiguration(jobCoreConfiguration, scriptCommandLine);
            }
            final LiteJobConfiguration liteJobConfiguration = this.createLiteJobConfiguration(jobTypeConfiguration, elasticJobConfig, jobProperties);
            final ElasticJob elasticJob = (ElasticJob)bean;
            this.initJobScheduler(elasticJob, elasticJobConfig, liteJobConfiguration, beanName, jobProperties);
        }
        return bean;
    }
    
    private void checkIdempotent(final ZsfJobProperties jobProperties) {
        try {
            if (CallType.CALL_CHAIN_BRANCH.equals(jobProperties.getCallType())) {
                return;
            }
            final String cron = jobProperties.getCron();
            if (StringUtils.isEmpty(cron)) {
                return;
            }
            final CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cron);
            final Date next1 = cronSequenceGenerator.next(new Date());
            final Date next2 = cronSequenceGenerator.next(next1);
            final long interval = next2.getTime() - next1.getTime();
            if (interval < 60000L && !IdempotentType.S.equals(jobProperties.getIdempotent())) {
                jobProperties.setIdempotent(IdempotentType.S);
            }
        }
        catch (Exception e) {
            ZsfJobBeanProcessor.log.warn("ZsfJob: checkIdempotent job[{}], warn: [{}]", (Object)jobProperties.getJobName(), (Object)e.getMessage());
        }
    }
    
    private JobCoreConfiguration createJobCoreConfiguration(final ZsfJobConfig elasticJobConfig, final ZsfJobProperties jobProperties) {
        Assert.hasLength(jobProperties.getJobName(), "elasticjob name is required.");
        Assert.hasLength(jobProperties.getCron(), "elasticjob cron is required.");
        if (CallType.CALL_CHAIN_BRANCH.equals(jobProperties.getCallType())) {
            jobProperties.setCron("0 0 0 ? * 6L 2085-2086");
        }
        final JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration.newBuilder(jobProperties.getJobName(), jobProperties.getCron(), jobProperties.getShardingTotalCount()).shardingItemParameters(jobProperties.getShardingItemParameters()).jobParameter(jobProperties.getJobParameter()).failover(jobProperties.isFailover()).misfire(jobProperties.isMisfire()).description(jobProperties.getDescription()).jobProperties(JobProperties.JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER.getKey(), elasticJobConfig.executorServiceHandler().getCanonicalName()).jobProperties(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER.getKey(), elasticJobConfig.jobExceptionHandler().getCanonicalName()).build();
        return jobCoreConfiguration;
    }
    
    private LiteJobConfiguration createLiteJobConfiguration(final JobTypeConfiguration jobTypeConfiguration, final ZsfJobConfig elasticJobConfig, final ZsfJobProperties jobProperties) {
        ZsfJobBeanProcessor.log.info("--namespace:{}", (Object)this.namespace);
        final boolean test = jobProperties.isTest();
        boolean disabled = jobProperties.isDisabled();
        if (!test && "local".equals(this.namespace)) {
            disabled = true;
        }
        if ("local".equals(this.namespace)) {
            jobProperties.setOverwrite(true);
        }
        final LiteJobConfiguration liteJobConfiguration = LiteJobConfiguration.newBuilder(jobTypeConfiguration).monitorExecution(jobProperties.isMonitorExecution()).maxTimeDiffSeconds(jobProperties.getMaxTimeDiffSeconds()).monitorPort(jobProperties.getMonitorPort()).jobShardingStrategyClass(elasticJobConfig.jobShardingStrategyClass().getCanonicalName()).reconcileIntervalMinutes(jobProperties.getReconcileIntervalMinutes()).disabled(disabled).overwrite(jobProperties.isOverwrite()).build();
        return liteJobConfiguration;
    }
    
    private void initJobScheduler(final ElasticJob elasticJob, final ZsfJobConfig elasticJobConfig, final LiteJobConfiguration liteJobConfiguration, final String beanName, final ZsfJobProperties jobProperties) {
        JobEventRdbConfiguration jobEventConfig = null;
        if (null != elasticJobConfig.eventTraceRdbDataSource()) {
            jobEventConfig = new JobEventRdbConfiguration(elasticJobConfig.eventTraceRdbDataSource());
        }
        final List<ElasticJobListener> listeners = new ArrayList<ElasticJobListener>(2);
        if (null != elasticJobConfig.listener()) {
            listeners.add(elasticJobConfig.listener());
        }
        if (jobProperties.isMonitorExecution() && null != elasticJobConfig.distributedListener()) {
            listeners.add((ElasticJobListener)elasticJobConfig.distributedListener());
        }
        ElasticJobListener[] elasticJobListeners = new ElasticJobListener[listeners.size()];
        if (!listeners.isEmpty()) {
            elasticJobListeners = listeners.toArray(elasticJobListeners);
        }
        ZsfSpringJobScheduler springJobScheduler = null;
        if (null != jobEventConfig) {
            springJobScheduler = new ZsfSpringJobScheduler(elasticJob, (CoordinatorRegistryCenter)this.zookeeperRegistryCenter, liteJobConfiguration, (JobEventConfiguration)jobEventConfig, elasticJobListeners);
        }
        else {
            springJobScheduler = new ZsfSpringJobScheduler(elasticJob, (CoordinatorRegistryCenter)this.zookeeperRegistryCenter, liteJobConfiguration, elasticJobListeners);
        }
        final String applicationName = this.env.getProperty("spring.application.name");
        new SchedulerThread(springJobScheduler, jobProperties, this.namespace, applicationName, this.zookeeperRegistryCenter, liteJobConfiguration).start();
    }
    
    static {
        log = LoggerFactory.getLogger((Class)ZsfJobBeanProcessor.class);
    }
}
